import { HttpClient } from '@angular/common/http';
import { Injectable } from '@angular/core';
import { AlertController, AlertOptions } from '@ionic/angular';
import { environment } from 'src/environments/environment';
import { pb } from 'src/pb';
import { dialogAlert } from './components/dialog';

@Injectable({
  providedIn: 'root',
})
export class HttpService {
  private error = '';
  constructor(private alertCtrl: AlertController, private http: HttpClient) {}

  async get<T>(url: string) {
    try {
      return await this.http.get<T>(url).toPromise();
    } catch (e) {
      if (await this.check(e)) {
        return await this.get(url);
      }
    }
  }

  async put<T>(url: string, param: any) {
    try {
      return await this.http.put<T>(url, param).toPromise();
    } catch (e) {
      if (await this.check(e)) {
        return this.put(url, param);
      }
    }
  }

  async del<T>(url: string) {
    try {
      return await this.http.delete<T>(url).toPromise();
    } catch (e) {
      if (await this.check(e)) {
        return this.del(url);
      }
    }
  }

  async post<T>(url: string, param: any) {
    try {
      return await this.http.post<T>(url, param).toPromise();
    } catch (e) {
      if (await this.check(e)) {
        return this.post(url, param);
      }
    }
  }

  async logout() {
    environment.user = '';
    try {
      await this.http.delete('/api/auth').toPromise();
    } catch (e) {}
    await this.auth();
  }

  async auth() {
    try {
      const user = await this.http.get('/api/auth').toPromise();
      if (user) {
        environment.user = user as string;
        return;
      }
    } catch (e) {
      const data = await this.dialog();
      await this.login(data.values);
    }
  }

  private async check(error: any) {
    this.error = error.error;
    switch (error.status) {
      case 401:
        await this.auth();
        return true;
      default:
        await dialogAlert(this.alertCtrl, {
          header: `异常 ${error.status}`,
          subHeader: error.message,
        });
        return false;
    }
  }

  private async login(user: pb.IUser) {
    try {
      const name = await this.http.post('/api/auth', user).toPromise();
      if (name) {
        environment.user = name as string;
        this.error = '';
        return;
      }
    } catch (e) {
      await this.check(e);
    }
  }

  private async dialog() {
    const alert = await this.alertCtrl.create(
      Object.assign(
        {
          inputs: [
            {
              label: '用户名',
              id: 'inputUser',
              name: 'user',
              value: '',
              type: 'text',
              placeholder: '用户登录名称',
            },
            {
              label: '密码',
              id: 'inputPassword',
              name: 'password',
              value: '',
              type: 'password',
              placeholder: '用户的登录密码',
            },
          ],
          buttons: [{ text: '取消', role: 'cancel' }, { text: '确定' }],
        } as AlertOptions,
        {
          header: '用户登录',
          subHeader: this.error,
        }
      )
    );
    await alert.present();

    const user = alert.querySelector('#inputUser') as HTMLInputElement;
    const password = alert.querySelector('#inputPassword') as HTMLInputElement;
    user.onkeydown = (ev: KeyboardEvent) => {
      if (user.value && ev.key === 'Enter') {
        password.focus();
      }
    };
    password.onkeydown = (ev: KeyboardEvent) => {
      if (password.value && user.value && ev.key === 'Enter') {
        alert.dismiss({
          values: { user: user.value, password: password.value },
        });
      }
    };

    user.focus();

    const ret = await alert.onDidDismiss();
    if (ret.role !== 'cancel' && ret.data) {
      return ret.data;
    }

    return { value: {} };
  }
}
